package string;

import java.util.HashMap;
import java.util.Map;

public class 有效数字 {
    class Solution2 {
        public boolean validNumber(String s) {
            Map[] states = {
                    new HashMap<Object, Object>() {{ put(' ', 0); put('s', 1); put('d', 2); put('.', 4); }}, // 0.
                    new HashMap<Object, Object>() {{ put('d', 2); put('.', 4); }},                           // 1.
                    new HashMap<Object, Object>() {{ put('d', 2); put('.', 3); put('e', 5); put(' ', 8); }}, // 2.
                    new HashMap<Object, Object>() {{ put('d', 3); put('e', 5); put(' ', 8); }},              // 3.
                    new HashMap<Object, Object>() {{ put('d', 3); }},                                        // 4.
                    new HashMap<Object, Object>() {{ put('s', 6); put('d', 7); }},                           // 5.
                    new HashMap<Object, Object>() {{ put('d', 7); }},                                        // 6.
                    new HashMap<Object, Object>() {{ put('d', 7); put(' ', 8); }},                           // 7.
                    new HashMap<Object, Object>() {{ put(' ', 8); }}                                         // 8.
            };
            int p = 0;
            char t;
            for(char c : s.toCharArray()) {
                if(c >= '0' && c <= '9') t = 'd';
                else if(c == '+' || c == '-') t = 's';
                else if(c == 'e' || c == 'E') t = 'e';
                else if(c == '.' || c == ' ') t = c;
                else t = '?';
                if(!states[p].containsKey(t)) return false;
                p = (int)states[p].get(t);
            }
            return p == 2 || p == 3 || p == 7 || p == 8;
        }
    }
    public static class Solution {

    /**
     * 判断给定的字符串是否为有效数字。
     *
     * @param s 输入字符串
     * @return 如果字符串是一个有效的数字则返回true，否则返回false
     */
    public boolean isNumber(String s) {
        int start = 0;             // 起点下标
        boolean dotFlag = false;   // 记录小数点是否出现
        boolean eFlag = false;     // 记录'e'或'E'是否出现
        boolean numberSeen = false; // 记录是否已经看到过数字

        // 读 前缀空格
        while (start < s.length() && s.charAt(start) == ' ')
            start++;

        // 处理符号
        if (start < s.length() && (s.charAt(start) == '+' || s.charAt(start) == '-'))
            start++;

        // 处理整数和小数部分
        for (int i = start; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c >= '0' && c <= '9') {
                numberSeen = true; // 看到数字
            } else if (c == '.') {
                if (eFlag || dotFlag) { // 已经出现过小数点或'e'
                    return false;
                }
                dotFlag = true;
            } else if (c == 'e' || c == 'E') {
                if (!numberSeen || eFlag) { // 没有看到数字或已经出现过'e'
                    return false;
                }
                eFlag = true;
                numberSeen = false; // 重置，以便检查'e'后的数字
                start = i + 1; // 更新起点
                break; // 结束循环，重新开始处理
            } else if (c == ' ') {
                if (i != s.length() - 1 || !numberSeen) { // 非末尾空格或没有看到数字
                    return false;
                }
            } else {
                return false; // 非法字符
            }
        }

        // 处理'e'后面的整数部分
        if (eFlag) {
            if (start < s.length() && (s.charAt(start) == '+' || s.charAt(start) == '-'))
                start++;
            for (int i = start; i < s.length(); i++) {
                char c = s.charAt(i);
                if (c >= '0' && c <= '9') {
                    numberSeen = true; // 看到数字
                } else if (c == ' ') {
                    if (i != s.length() - 1 || !numberSeen) { // 非末尾空格或没有看到数字
                        return false;
                    }
                } else {
                    return false; // 非法字符
                }
            }
        }

        return numberSeen;
    }

    public static void main(String[] args) {
        Solution solution = new Solution();
        String[] validNumbers = {"2", "0089", "-0.1", "+3.14", "4.", "-.9", "2e10", "-90E3", "3e+7", "+6e-1", "53.5e93", "-123.456e789"};
        String[] invalidNumbers = {"abc", "1a", "1e", "e3", "99e2.5", "--6", "-+3", "95a54e53"};

        for (String num : validNumbers) {
            System.out.println(num + ": " + solution.isNumber(num));
        }

        for (String num : invalidNumbers) {
            System.out.println(num + ": " + solution.isNumber(num));
        }
    }
}


}
